package com.headhunter.portlet;

import java.util.ArrayList;
import java.util.List;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;

import com.headhunter.portlet.service.VocationService;
import com.headhunter.portlet.service.impl.VocationServiceImpl;
import com.headhunter.portlet.dao.VocationDAO;
import com.headhunter.portlet.domain.Vocation;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

/**
 * Unit test for VocationService.
 * 
 * @author Denis Skalenko
 */
public class VocationServiceTestCase {
	/**
	 * Class underTest
	 */
	private VocationService vocationService;

	/**
	 * Mock object
	 */
	private VocationDAO mock;

	@Before
	public void setUp() throws Exception {
		// Starting mock object
		this.vocationService = new VocationServiceImpl();
		this.mock = createMock(VocationDAO.class);
		this.vocationService.setDao(this.mock);
	}

	/**
	 * This method test the getVocationsListOrderByDate when none value is
	 * returned In that case, the method must return an Empty
	 * {@link java.util.List}
	 */
	@Test
	public void getVocationsListOrderByDateWhenNoneVocationIsRetrieve() {
		// Adding behavior for that method
		expect(this.mock.getVocationsListOrderByDate()).andReturn(
				new ArrayList<Vocation>());
		replay(this.mock);
		assertEquals("Error : Vocations list must be empty", true,
				this.vocationService.vocationsListOrderByDate().isEmpty());
	}

	/**
	 * This method test the GetVocationsListOrderByDate when only ONE value is
	 * returned
	 */
	@Test
	public void getVocationsListOrderByDateWhenOneVocationIsRetrieved() {
		int size = 1;
		List<Vocation> listVocation = getListVocation(size);
		assertEquals(false, listVocation.isEmpty());
		assertEquals(size, listVocation.size());
		// Testing the returned value
		Vocation oneVocation = listVocation.get(0);
		assertEquals("Test name " + (size - 1), oneVocation.getVocationName());
	}

	/**
	 * This method test the GetVocationsListOrderByDate when many value is
	 * returned
	 */
	@Test
	public void getVocationsListOrderByDateWhenManyVocationIsRetrieved() {
		int size = 4;
		List<Vocation> listVocation = getListVocation(size);
		assertEquals(false, listVocation.isEmpty());
		assertEquals(size, listVocation.size());
		for (int i = 0; i < size; i += 2) {
			assertTrue(listVocation.get(i).getStartDate()
					.compareTo(listVocation.get(i + 1).getStartDate()) <= 0);
		}
	}

	private List<Vocation> getListVocation(int size) {
		List<Vocation> vocations = addVocation(size);
		// Adding behavior for that method
		expect(this.mock.getVocationsListOrderByDate()).andReturn(vocations);
		replay(this.mock);
		// Testing the return
		return this.vocationService.vocationsListOrderByDate();
	}

	private List<Vocation> addVocation(int size) {
		List<Vocation> vocations = new ArrayList<Vocation>();
		Vocation vocation;
		// Adding vocations
		for (int i = 0; i < size; i++) {
			vocation = new Vocation();
			vocation.setCompanyId((long) i);
			vocation.setVocationName("Test name " + i);
			vocation.setSalary("Test salary " + i);
			vocation.setExperience("Test experience " + i);
			vocation.setDescription("Test descriptin" + i);
			vocation.setStartDate(getDate(i));
			vocations.add(vocation);
		}
		return vocations;
	}

	private Date getDate(int howDate) {
		long dateTime = howDate * 24 * 60 * 60 * 1000;
		return new Date(System.currentTimeMillis() + dateTime);
	}

}
